package com.baidu.bas.core.controller;

import com.baidu.bas.annotation.sub_erupt.Drill;
import com.baidu.bas.annotation.sub_erupt.Link;
import com.baidu.bas.core.annotation.EruptRecordOperate;
import com.baidu.bas.core.annotation.EruptRouter;
import com.baidu.bas.core.constant.EruptRestPath;
import com.baidu.bas.core.exception.EruptNoLegalPowerException;
import com.baidu.bas.core.service.EruptCoreService;
import com.baidu.bas.core.service.EruptService;
import com.baidu.bas.core.util.AnnotationUtil;
import com.baidu.bas.core.util.EruptUtil;
import com.baidu.bas.core.util.ReflectUtil;
import com.baidu.bas.core.view.EruptApiModel;
import com.baidu.bas.core.view.EruptModel;
import com.baidu.bas.core.view.Page;
import com.baidu.bas.core.view.TableQueryVo;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;

/**
 * @author liyuepeng
 * @date 2020-03-06
 */
@RestController
@RequestMapping(EruptRestPath.ERUPT_DATA)
public class EruptDrillController {

    @Autowired
    private Gson gson;

    @Autowired
    private EruptModifyController eruptModifyController;

    @Autowired
    private EruptService eruptService;

    @PostMapping("/dict/{erupt}/{code}/{id}")
    @EruptRouter(authIndex = 2, verifyType = EruptRouter.VerifyType.ERUPT)
    public EruptApiModel dict(@PathVariable("erupt") String eruptName,
                      @PathVariable("code") String code,
                      @PathVariable("id") String id,
                      @RequestBody(required = false) TableQueryVo tableQueryVo) throws IllegalAccessException {
        if(tableQueryVo==null){
            tableQueryVo = new TableQueryVo().setPage(0).setSize(10000);
        }
        EruptModel eruptModel = EruptCoreService.getErupt(eruptName);
        Link link = null;
        for (Drill drill : eruptModel.getErupt().drills()) {
            if (drill.code().equals(code)) {
                link = drill.link();
            }
        }

        if (null != link) {
            // 当前model 要 drill 到下一个表时的字段, 即: 外键的值
            Field field = ReflectUtil.findClassField(eruptModel.getClazz(), link.column());
            field.setAccessible(true);
            Object data = AnnotationUtil.getEruptDataProcessor(eruptModel.getClazz())
                    .findDataByField(eruptModel,"code",id);
            if(data==null){
                return EruptApiModel.successApi(new Page());
            }
            Object val = field.get(data);
            if (null == val) {
                return EruptApiModel.successApi(new Page());
            }

            if (!eruptService.verifyIdPermissions(eruptModel, String.valueOf(eruptModel.getIdValue(data)))) {
                throw new EruptNoLegalPowerException();
            }

            EruptModel linkModel = EruptModel.of(link.linkErupt());
            Page eruptData = eruptService.getEruptData(
                    EruptCoreService.getErupt(link.linkErupt().getSimpleName()),
                    tableQueryVo, null, String.format("%s = '%s'",
                            linkModel.asTableName() + "." + link.joinColumn(), val));
            return EruptApiModel.successApi(eruptData);
        }
        throw new EruptNoLegalPowerException();
    }

    @PostMapping("/drill/{erupt}/{code}/{id}")
    @EruptRouter(authIndex = 2, verifyType = EruptRouter.VerifyType.ERUPT)
    public EruptApiModel drill(@PathVariable("erupt") String eruptName,
                      @PathVariable("code") String code,
                      @PathVariable("id") String id,
                      @RequestBody(required = false) TableQueryVo tableQueryVo) throws IllegalAccessException {
        if(tableQueryVo==null){
            tableQueryVo = new TableQueryVo();
        }
        EruptModel eruptModel = EruptCoreService.getErupt(eruptName);
        Link link = null;
        for (Drill drill : eruptModel.getErupt().drills()) {
            if (drill.code().equals(code)) {
                link = drill.link();
            }
        }

        if (null != link) {
            if (!eruptService.verifyIdPermissions(eruptModel, id)) {
                throw new EruptNoLegalPowerException();
            }
            // 当前model 要 drill 到下一个表时的字段, 即: 外键的值
            Field field = ReflectUtil.findClassField(eruptModel.getClazz(), link.column());
            field.setAccessible(true);
            Object data = AnnotationUtil.getEruptDataProcessor(eruptModel.getClazz())
                    .findDataById(eruptModel, EruptUtil.toEruptId(eruptModel, id));
            Object val = field.get(data);
            if (null == val) {
                return EruptApiModel.successApi(new Page());
            }
            EruptModel linkModel = EruptModel.of(link.linkErupt());
            Page eruptData = eruptService.getEruptData(
                    EruptCoreService.getErupt(link.linkErupt().getSimpleName()),
                    tableQueryVo, null, String.format("%s = '%s'",
                            linkModel.asTableName() + "." + link.joinColumn(), val));
            return EruptApiModel.successApi(eruptData);
        }
        throw new EruptNoLegalPowerException();
    }

    @PostMapping("/add/{erupt}/drill/{code}/{id}")
    @ResponseBody
    @EruptRecordOperate(desc = "新增")
    @EruptRouter(authIndex = 2, verifyType = EruptRouter.VerifyType.ERUPT)
    public EruptApiModel drillAdd(@PathVariable("erupt") String erupt,
                                  @PathVariable("code") String code,
                                  @PathVariable("id") String id,
                                  @RequestBody String jsonData,
                                  HttpServletRequest request, HttpServletResponse response) throws Exception {
        EruptModel eruptModel = EruptCoreService.getErupt(erupt);
        Link link = null;
        for (Drill drill : eruptModel.getErupt().drills()) {
            if (code.equals(drill.code())) {
                link = drill.link();
            }
        }
        if (null != link) {
            if (!eruptService.verifyIdPermissions(eruptModel, id)) {
                throw new EruptNoLegalPowerException();
            }
            JsonObject jo = new JsonObject();
            String joinColumn = link.joinColumn();
            Field field = ReflectUtil.findClassField(eruptModel.getClazz(), link.column());
            field.setAccessible(true);
            Object val = field.get(AnnotationUtil.getEruptDataProcessor(eruptModel.getClazz())
                    .findDataById(eruptModel, EruptUtil.toEruptId(eruptModel, id)));
            if (joinColumn.contains(".")) {
                String[] jc = joinColumn.split("\\.");
                JsonObject jo2 = new JsonObject();
                jo2.addProperty(jc[1], val.toString());
                jo.add(jc[0], jo2);
            } else {
                jo.addProperty(joinColumn, val.toString());
            }
            return eruptModifyController.addEruptData(link.linkErupt().getSimpleName(), jsonData, jo,request,response);
        }
        throw new EruptNoLegalPowerException();
    }


}
